import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class Ex1 {
	int j = 2;
	String s = "aaaa";
}

public class AssignmentTest {

	public static void main(final String[] args) throws SecurityException, NoSuchMethodException, ClassNotFoundException,
			InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

		final Ex1 e1 = new Ex1();
		final Ex1 e2 = e1;

		e2.j = 5;
		e2.s = "asdasdas";

		System.out.println(e1.j);
		System.out.println(e2.j);
		System.out.println(e1.s);
		System.out.println(e2.s);

		String s1 = "sssss";
		final String s2 = s1;
		s1 = "s11Changed";

		System.out.println("s1=" + s1);
		System.out.println("s2=" + s2);

		// reflectionExample();

		// changeReferenceExample();
		int i = 2;
		System.out.println(++i);
		System.out.println(i++);
	}

	private static void changeReferenceExample() {
		final ExClass exClass = new ExClass();
		referenceEx(exClass);
		System.out.println(exClass.i);

		final int i = 2;
		change(i);
		System.out.println("After i was changed (but not changed):" + i);
		final byte a = (byte) 129;
		System.out.println("a==" + a);

		final ExClass ass = null;
		System.out.println("aaas=" + ass.i);
	}

	static void change(int i) {
		i = 0;
	}

	static void referenceEx(ExClass s) {
		s.i = 3;
		s = null;
		System.out.println(s);

	}

	private static void reflectionExample() throws ClassNotFoundException, InstantiationException, IllegalAccessException,
			NoSuchMethodException, InvocationTargetException {
		final Class cls = Class.forName("ClassWithPrivateMethods");
		final Object obj = cls.newInstance();

		// call the printIt method
		final Method method = cls.getDeclaredMethod("print");
		method.setAccessible(true);
		method.invoke(obj, null);
	}

	private static void intStrangeBehavior() {
		// final int i = 'a';
		final int v = 128;

		final Integer inte1 = v;
		final Integer inte2 = v;
		System.out.println("inte1==inte2:" + (inte1 == inte2));
		final boolean b = inte1.equals(inte2);
		System.out.println("inte1 equals inte2:" + b);

		final String s1 = "s1";
		final String s2 = "s1";

		final ExClass sClass = new ExClass();

		sClass.i = 5;
	}

	static void print(final int i) {
		System.out.println(i);
	}

}

final class ExClass {
	String s1111 = "blabla";
	static int i = 2;
	String s = "string" + "_string 1" + i;

	private void concatenate(final String s) {
		final StringBuilder sb = new StringBuilder();

		final String finalS = s + "asdasd" + s1111 + s;

		House h = new House();
		h = h.nrOfWindows(2).nrOfDoors(3);

	}
}

class House {
	int nrOfWindows;
	int nrOfDoors;
	int m;
	int n;
	int k;

	House() {
		super();
	}

	public House nrOfDoors(final int l) {
		nrOfDoors = l;
		return this;
	}

	public House nrOfWindows(final int i) {
		nrOfWindows = i;
		return this;
	}

	public int getI() {
		return nrOfWindows;
	}

	public void setI(final int i) {
		nrOfWindows = i;
	}

	public int getJ() {
		return nrOfDoors;
	}

	public void setJ(final int j) {
		nrOfDoors = j;
	}

	public int getM() {
		return m;
	}

	public void setM(final int m) {
		this.m = m;
	}

	public int getN() {
		return n;
	}

	public void setN(final int n) {
		this.n = n;
	}

	public int getK() {
		return k;
	}

	public void setK(final int k) {
		this.k = k;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = (prime * result) + nrOfWindows;
		result = (prime * result) + nrOfDoors;
		result = (prime * result) + k;
		result = (prime * result) + m;
		result = (prime * result) + n;
		return result;
	}

	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		final House other = (House) obj;
		if (nrOfWindows != other.nrOfWindows) {
			return false;
		}
		if (nrOfDoors != other.nrOfDoors) {
			return false;
		}
		if (k != other.k) {
			return false;
		}
		if (m != other.m) {
			return false;
		}
		if (n != other.n) {
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		final String format = String.format("House [i=%s, j=%s, m=%s, n=%s, k=%s]", nrOfWindows, nrOfDoors, m, n, k);
		return format;
	}

}
